package com.ycx.ycxmybatismanagement.aop;

import com.alibaba.fastjson2.JSON;
import com.ycx.ycxmybatismanagement.entity.OperateLog;
import com.ycx.ycxmybatismanagement.mapper.LoginMapper;
import com.ycx.ycxmybatismanagement.mapper.OperateLogMapper;
import com.ycx.ycxmybatismanagement.util.JwtUtils;
import com.ycx.ycxmybatismanagement.util.UserThreadLocal;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;

@Component
@Aspect
@Slf4j
public class LogAspect {
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private OperateLogMapper operateLogMapper;
    @Around("@annotation(myLog)")
    public Object around(ProceedingJoinPoint pjp,MyLog myLog) throws Throwable{
//        //操作人、操作时间、执行方法的全类名、执行方法名、方法运行时参数、返回值
//        String token = request.getHeader("token");
//        ////解析token中的userId
//        Claims claims = JwtUtils.parseJWT(token);
//        //获取操作人id ,和操作人的名称
//        Integer id = claims.get("id", Integer.class);
//        String username = claims.get("username", String.class);

        //获取线程中的数据
        UserThreadLocal.UserInfo userInfo = UserThreadLocal.getUserInfo();
        Integer id = userInfo.getId();
        String username = userInfo.getName();
        //从pjp中获取类名,执行方法,方法运行时参数,返回值
        Signature signature = pjp.getSignature();
        String methodName = signature.getName();
        String className =signature.getDeclaringTypeName();
        Object[] args = pjp.getArgs();//参数
        long start = System.currentTimeMillis();
        Object result = pjp.proceed();
        long end =System.currentTimeMillis();
        long costTime = (end - start);
        OperateLog log = OperateLog.builder().
                operateUser(id)
                .operateName(username)
                .className(className)
                .methodName(methodName)
                .methodParams(args == null ? "" : Arrays.toString(args)) //方法名
                .returnValue(result == null ? "" : result.toString())
                .costTime(costTime)
                .methodDesc(myLog.desc())
                .operateTime(LocalDateTime.now())
                .build();
        operateLogMapper.insertOperateLog(log);
        return result;
    }
}
